#include "widget.h"
#include "ui_widget.h"
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <signal.h>
#include <iostream>
#include <QDebug>
#include <QListWidget>
#include <list>
#include <algorithm>
#include <lrc.h>
#include <dirent.h>
#include <QListWidgetItem>


typedef struct DATA
{
    int a;
    Widget *b;
} DATA;






Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);


}


Widget::Widget(int fd0 , QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    this->setWindowTitle("wyy music");

    // -------fifo_fd get---------
    fifo_fd = open("./player_fifo" , O_RDWR);
    f_s = fd0;
    song_num = 0;
    song_index = -1;
    display_flag = 1;


    // create a listwidget_lrc
    QListWidget *listwidget_lrc = new QListWidget(this);

    listwidget_lrc->setFixedSize(340, 80);
    listwidget_lrc->move(365, 80);
    listwidget_lrc->setStyleSheet("background-color:transparent"); // 设置背景透明
    listwidget_lrc->setFrameShape(QListWidget::NoFrame);           // 设置边框透明


    // get song name list
    QListWidgetItem *itemh = new QListWidgetItem(QString("歌曲列表"));
    itemh->setFlags((Qt::ItemFlag)0); // 设置当前行不可点击并灰显
    itemh->setFont(QFont("楷体", 20));
    itemh->setTextAlignment(Qt::AlignCenter);
    itemh->setBackground(QBrush(QColor(80, 126, 211))); // 设置背景色
    itemh->setTextColor(Qt::black);                     // 设置字体颜色
    itemh->setTextAlignment(Qt::AlignCenter);

    ui->listWidget_song->addItem(itemh);


    lrc_head = new S_LRC_HEAD;
    lrc_head->ti = (char *)malloc(20);
    lrc_head->al = (char *)malloc(20);
    lrc_head->ar = (char *)malloc(20);

    get_song_name_list();


    // use two thread to send and recv mplayer`s

    DATA *w = (DATA *)malloc(sizeof(DATA));
       pthread_t tid1;
       pthread_create(&tid1, NULL, send_cmd, NULL);
       pthread_detach(tid1);
       w->b = (Widget *)malloc(sizeof(Widget));
       w->a = fd0;
       w->b = this;
       pthread_t tid2;
       pthread_create(&tid2, NULL, recv_msg, (void *)w);
       pthread_detach(tid2);


//    lrc_list = (list<lrc> *) malloc(sizeof(lrc) * 100);
    lrc_list = new list<lrc>;

//    lyrics();


    // 使用QTimer类实现定时
    QTimer *mytime = new QTimer(this);
    mytime->start(1000);

    connect(mytime, &QTimer::timeout, [=]()
                {
            //qDebug() << "aaaaaaaaaaaaaaaabbb" << l1 << endl;
            static int t=0; //歌曲歌词时间匹配成功次数
            static int l2 = l1; //l2保存l1前一次的值
            static int m = 0; //执行到歌词当前第m句
            static int k=2; //歌词显示位置
            if(l2 != l1)
            {
                if(l2 != N-1)
                {
                    item[l2]->setBackground(QBrush(QColor(255, 255, 255))); //设置背景色
                    item[l2]->setTextColor(Qt::black); //设置字体颜色
                }
                l2 = l1;
                t=0;
                m=0;
                k=2;
                ui->label_1->setPalette(pa2);
                ui->label_2->setPalette(pa2);
                ui->label_3->setPalette(pa2);
                ui->label_4->setPalette(pa2);
                ui->label_5->setPalette(pa2);
                item[l1]->setBackground(QBrush(QColor(205, 205, 205))); //设置背景色
                item[l1]->setTextColor(Qt::red); //设置字体颜色
                //打开对应文件
                char buf_fd[64]="";
                sprintf(buf_fd,"../Music_player/lyrics/%s",lrc[l1]);

                FILE *fp;
                if((fp = fopen(buf_fd, "a+")) == NULL)
                {
                    printf("fail to fopen\n");
                    return -1;
                }
                //循环清空容器
                int a1=h->size();
                for(int j=0;j <  a1;j++)
                {
                    h->removeAt(0);
                }
                lrc_list(fp,h,a); //解析歌词
                listwidget_lrc->clear();
                for(int i=1;i<4;i++)
                {
                    listwidget_lrc->addItem(QString(a[i]));
                    //将QListwidgst的（i-1）行灰显且不可点击
                    listwidget_lrc->item(i-1)->setFlags(Qt::ItemIsUserCheckable);
                    listwidget_lrc->item(i-1)->setTextAlignment(Qt::AlignCenter);
                }

                //-------------------------------------------------------------------------------------
                qSort(h->begin(),h->end(),myCompareByClass()); //QList容器排序
                fclose(fp);
            }
    //        for(int k=0;k<h->size();k++)
    //        {
    //            qDebug() << h->size() << endl;
    //            printf("%.3f\n",h->at(k).time);
    //            printf("%s\n",h->at(k).name.toUtf8().data());
    //        }


            if((lrc[l1]!=NULL) && (a[0] != NULL))
            {
                int diff=0;
                if(m < h->size())
                {
                    diff = h->at(m).time - time_d;
                }
                else if(m == h->size())
                {
                    diff = 0;
                }
                else
                {
                    diff = 2;
                }
                if(diff < 0)
                {diff = diff * (-1);}
                if(diff <= 0.5)
                {
                    m++;
                    t++;
                }

                if(t==1)
                {
                    ui->label_1->setPalette(pa1);
                    ui->label_2->setPalette(pa2);
                    ui->label_3->setPalette(pa2);
                    ui->label_4->setPalette(pa2);
                    ui->label_5->setPalette(pa2);
                }
                if(t==2)
                {
                    ui->label_1->setPalette(pa2);
                    ui->label_2->setPalette(pa1);
                    ui->label_3->setPalette(pa2);
                    ui->label_4->setPalette(pa2);
                    ui->label_5->setPalette(pa2);
                }
                if(t==3)
                {
                    ui->label_1->setPalette(pa2);
                    ui->label_2->setPalette(pa2);
                    ui->label_3->setPalette(pa1);
                    ui->label_4->setPalette(pa2);
                    ui->label_5->setPalette(pa2);
                }

                if((t>=4)&&(t<=h->size()-2))
                {
                    k=m-1;
                }

                if(t==h->size()-1)
                {
                    ui->label_1->setPalette(pa2);
                    ui->label_2->setPalette(pa2);
                    ui->label_3->setPalette(pa2);
                    ui->label_4->setPalette(pa1);
                    ui->label_5->setPalette(pa2);
                }
                if(t==h->size())
                {
                    ui->label_1->setPalette(pa2);
                    ui->label_2->setPalette(pa2);
                    ui->label_3->setPalette(pa2);
                    ui->label_4->setPalette(pa2);
                    ui->label_5->setPalette(pa1);
                }
                if(t==h->size()+1)
                {
                    if((time_s - time_d) < 2.0f)
                    {
                        this->myslot_down();
                    }
                }
                ui->label_1->setText(h->at(k-2).name);
                ui->label_2->setText(h->at(k-1).name);
                ui->label_3->setText(h->at(k).name);
                ui->label_4->setText(h->at(k+1).name);
                ui->label_5->setText(h->at(k+2).name);

    //            qDebug() << "t====" << t << endl;
    //            qDebug() << "h.size===" << h->size() << endl;
                //t++;

            } });






    connect(listwidget, &QListWidget::currentTextChanged, this, &Widget::myslot); // 歌曲列表

    connect(ui->label_action, &Mylabel::mysignal, this, &Widget::action); // 开始按钮

    connect(ui->horizontalSlider_Volume, &QSlider::valueChanged, this, &Widget::volume_change); // 音量控制

    connect(ui->label_Volume, &Mylable_vol::mysignal_vol, this, &Widget::volume); // 音量按钮

    connect(ui->label_up, &Mylabel_ud::mysignal_ud, this, &Widget::myslot_up); // 上一曲

    connect(ui->label_down, &Mylabel_ud::mysignal_ud, this, &Widget::myslot_down); // 下一曲



}



Widget::~Widget()
{
    delete ui;
    fclose(fp);
    free(lrc_head->al);
    free(lrc_head->ar);
    free(lrc_head->ti);

    delete lrc_head;

//    lrc_list->clear();

}



void Widget::get_song_name_list()
{
    // open file dir

    DIR * dir = NULL;
    if( (dir = opendir("../IOT_player/song") ) == NULL )
    {
        perror("fail to open song dir");
        exit(-1);
    }

    struct dirent * dirp;
    while(1)
    {
        dirp = readdir(dir);
        if(dirp == NULL)
        {
            break;
        }else if(dirp->d_type == DT_REG)  // get common file song
        {

            songs[song_num] = (char *)malloc(32);
            strcpy(songs[song_num] , dirp->d_name);

            qList_items[song_num] = new QListWidgetItem;
            qList_items[song_num]->setText(QString(songs[song_num]));
            ui->listWidget_song->addItem(qList_items[song_num]);

            song_num++;

        }else{

        }

    }

}



void* Widget::recv_msg(void *arg)
{

    DATA *w = (DATA *)arg;
        Widget *p = w->b;
        int fd0 = w->a;
        while (1)
        {
            char buf[64] = "";
            if (read(fd0, buf, sizeof(buf)) == -1)
            {
                perror("fail to read");
            }
            // qDebug() << buf << "qqqq-----" <<endl;
            if (strncmp(buf, "ANS_LENGTH", strlen("ANS_LENGTH")) == 0)
            {
                float stime = 0.0f;
                sscanf(buf, "ANS_LENGTH=%f", &stime);
                time_s = stime;
            }
            if (strncmp(buf, "ANS_TIME_POSITION", strlen("ANS_TIME_POSITION")) == 0)
            {
                float time = 0.0f;
                sscanf(buf, "ANS_TIME_POSITION=%f", &time);
                time_d = time;
                emit p->gettime(time);
            }
        }

}


void* Widget::send_msg(void *arg)
{
    while(1)
    {
        usleep(500 * 1000);
        if(display_flag % 2 == 0)  // displaying
        {
            if(write(fifo_fd , "get_time_length\n") , strlen("get_time_length\n") == -1)
            {
                perror("fail to get_time_length from mplayer");
            }
        }

        usleep(500 * 1000);
        if(display_flag % 2 == 0)  // displaying
        {
            if(write(fifo_fd , "get_time_pos\n") , strlen("get_time_pos\n") == -1)
            {
                perror("fail to get_time_pos from mplayer");
            }
        }


    }
}



void Widget::action(QPixmap pixmap) // 歌曲暂停
{
    ui->label_action->setPixmap(pixmap);
    if (write(fifo_fd, "pause\n", strlen("pause\n")) == -1) // 歌曲暂停
    {
        perror("fail to pause song");
    }
    display_flag++;
}




void Widget::volume_remove(QPixmap pixmap) // 静音控制
{
    if (display_flag % 2 == 0)
    {
        static int i = 0;
        ui->label_Volume->setPixmap(pixmap);

        mkfifo("myfifo", 0664);


        if (i % 2 == 0)
        {
            if (write(fifo_fd, "mute 1\n", strlen("mute 1\n")) == -1) // 歌曲vloume open
            {
                perror("write");
            }
        }
        else
        {
            if (write(fifo_fd, "mute 0\n", strlen("mute 0\n")) == -1) // 歌曲静音
            {
                perror("write");
            }
        }
        i++;
    }
}


void Widget::myslot(QString str) // 切歌
{
    mkfifo("myfifo", 0664);

    int fd;
    if ((fd = open("myfifo", O_WRONLY)) == -1)
    {
        perror("fail to open");
    }
    char buf[128] = "";
    sprintf(buf, "loadfile ../Music_player/song/%s\n", str.toUtf8().data());
    if (write(fd, buf, strlen(buf)) == -1)
    {
        perror("write");
    }
    for (int i = 0; i < s2; i++)
    {
        if ((song[i] != NULL) && (strcmp(str.toUtf8().data(), song[i])) == 0)
        {
            s1 = i;
            l1 = i;
        }
    }
    char *str1 = strtok(str.toUtf8().data(), ".");
    ui->label_s_name->setText(QString(str1));
}


void Widget::volume_change(int value) // 调节音量
{
    if (flag1 % 2 == 0)
    {
        mkfifo("myfifo", 0664);

        int fifo_fd;
        if ((fifo_fd = open("myfifo", O_WRONLY)) == -1)
        {
            perror("fail to open");
        }
        char buf[128] = "";
        sprintf(buf, "volume %d 1\n", value);
        if (write(fifo_fd, buf, strlen(buf)) == -1)
        {
            perror("write");
        }
    }
}

void Widget::myslot_up()
{
    mkfifo("myfifo", 0664);

    int up_fd;
    if ((up_fd = open("myfifo", O_WRONLY)) == -1)
    {
        perror("fail to open");
    }
    char buf[128] = "";
    int s3 = 0;
    if (s1 == 0)
    {
        s3 = s2;
    }
    else if (s1 == 1)
    {
        s3 = 0;
    }
    else
    {
        s3 = (s1 - 1) % s2;
    }
    s1 = s3;
    l1 = s3;
    sprintf(buf, "loadfile ../Music_player/song/%s\n", song[s3]);
    if (write(up_fd, buf, strlen(buf)) == -1)
    {
        perror("write");
    }
    char *str1 = (char *)malloc(32);
    bzero(str1, 0);
    strcpy(str1, song[s3]);
    char *str2 = NULL;
    bzero(str2, 0);
    str2 = strtok(str1, ".");
    ui->label_s_name->setText(QString(str2));
}

void Widget::myslot_down()
{
    mkfifo("myfifo", 0664);

    int down_fd;
    if ((down_fd = open("myfifo", O_WRONLY)) == -1)
    {
        perror("fail to open");
    }
    char buf[128] = "";
    int s3 = 0;
    if (s1 == s2)
    {
        s3 = 0;
    }
    else if (s1 == s2 - 1)
    {
        s3 = s2;
    }
    else
    {
        s3 = (s1 + 1) % s2;
    }
    s1 = s3;
    l1 = s3;
    sprintf(buf, "loadfile ../Music_player/song/%s\n", song[s3]);
    if (write(down_fd, buf, strlen(buf)) == -1)
    {
        perror("write");
    }
    char *str1 = (char *)malloc(32);
    bzero(str1, 0);
    strcpy(str1, song[s3]);
    char *str2 = NULL;
    bzero(str2, 0);
    str2 = strtok(str1, ".");
    ui->label_s_name->setText(QString(str2));
}

void Widget::get_time(int time)
{
    char sti1[8] = "";
    sprintf(sti1, "%02d:%02d", time / 60, time % 60);
    ui->label_time1->setText(QString(sti1));

    char sti2[8] = "";
    sprintf(sti2, "%02d:%02d", (int)time_s / 60, (int)time_s % 60);
    ui->label_time2->setText(QString(sti2));

    if (((int)time != 0) && ((int)time_s != 0))
    {
        int t = time * 100 / time_s;
        ui->horizontalSlider->setValue(t);
    }
}




/**
 * @brief Widget::on_pushButton_display_clicked
 *  this function is to play music
 */

void Widget::on_pushButton_display_clicked()
{


    qDebug() << "click display button! :"  << fifo_fd;
    // display
    write(fifo_fd , "loadfile /home/xiaye/song_resource/song/Diamonds.mp3\n" , strlen("loadfile /home/xiaye/song_resource/song/Diamonds.mp3\n"));


}

void Widget::on_pushButton_pause_clicked()
{
    write(fifo_fd , "pause\n" , strlen("pause\n"));
}


void Widget::on_pushButton_display_lrc_clicked()
{

    qDebug() <<"click display lrc";
    if( (fp = fopen("../IOT_player/lyrics/简单爱.lrc", "a+")) == NULL )
    {
        perror("fail to open lrc");
     // qDebug() << "fail to open lrc file";
    }

//    memset(lrc_head->ti ,20,1 );
//    memset(lrc_head->ar ,20,1 );
//    memset(lrc_head->al ,20,1 );
    bzero(lrc_head->ti,20);
    bzero(lrc_head->ar,20);
    bzero(lrc_head->al,20);

    lrc::load_lrc_file(fp,lrc_list,lrc_head);


}

void Widget::on_pushButton_find_lrc_with_time_clicked()
{
    // 1. get the time in text box
//    cout << ui->textEdit_findlrc_time <<endl;


    // 2. get this lrc from list which is bigest one smaller than the time

    // printf this lrc

    qDebug() << "resolve :" <<lrc_head->ti;
    qDebug() << "resolve :" <<lrc_head->al;
    qDebug() << "resolve :" <<lrc_head->ar;
}

void Widget::on_listWidget_song_itemDoubleClicked(QListWidgetItem *item)
{

    char command_str[128];
    bzero(command_str , 0);

    sprintf(command_str , "loadfile /home/xiaye/song_resource/song/%s\n" , item->text().toStdString().c_str() );



    qDebug() <<  command_str;
    write(fifo_fd , command_str , strlen(command_str));


}
